Procesamiento de datos
Unidad 2
La manipulación de datos agrupa todas las tareas necesarias para la gestión de las variables:
dplyr es el paquete para transformar datos que pertenece al ecosistema tidyverse
Implementa una gramática “humana”
Está constituido por funciones definidas como “verbos”
Las funciones primarias son: select(), filter(), arrange(), mutate() y summarise()
Otras funciones útiles son: rename(), group_by(), count(), if_else(), case_when(), beteewn(), across(), rowwise(), etc.
La función select() del inglés seleccionar, sirve para seleccionar variables (columnas) de una tabla de datos.
Además existe un abanico de funciones que ayudan a una mejor selección de nombres de variables.
everything(): coincide con todas las variables.
group_cols(): seleccione todas las columnas de agrupación.
starts_with(): comienza con un prefijo.
ends_with(): termina con un sufijo.
contains(): contiene una cadena literal.
matches(): coincide con una expresión regular.
num_range(): coincide con un rango numérico como x01, x02, x03.
all_of(): coincide con nombres de variables en un vector de caracteres.
any_of(): igual que all_of(), excepto que no se genera ningún error para los nombres que no existen.
where(): aplica una función a todas las variables y selecciona aquellas para las cuales la función regresa TRUE.
[1] "Anio" "Escuela" "F1_FNac"
[4] "F2_Edad" "F3_Sexo" "F4_Abuelos"
[7] "F4_Hermanos" "F4_Madrastra" "F4_Madre"
[10] "F4_Otros" "F4_Padrastro" "F4_Padre"
[13] "F5_Amigo" "F5_Familiar" "F5_Nadie"
[16] "F5_Novio" "F5_Otro" "F5_Profesional"
[19] "F6_amigos" "F7_Acompaniado" "F8_novio"
[22] "F9_CuantoTiempo" "FKEY" "GlobalRecordId"
[25] "H1_Alcohol" "H1_Bblancas" "H1_Cerveza"
[28] "H1_CuantosDias" "H1_CuantosVasos" "H1_Fernet"
[31] "H1_Otra" "H1_Vino" "H2_Cigarrillos"
[34] "H2_Cuantos" "H3_Cuantos" "H3_Marihuana"
[37] "H4_Cual" "H4_OtraDroga" "H5_HoraDormir"
[40] "H6_Almuerzo" "H6_Cena" "H6_Desayuno"
[43] "H6_Merienda" "H6_Motivado" "H6A_Calle"
[46] "H6A_Casa" "H6A_ConQuien" "H6A_Escuela"
[49] "H6C_Calle" "H6C_Casa" "H6C_ConQuien"
[52] "H6C_Escuela" "H6D_Calle" "H6D_Casa"
[55] "H6D_ConQuien" "H6M_Calle" "H6M_Casa"
[58] "H6M_ConQuien" "H6M_Escuela" "HD6_Escuela"
[61] "S1_ControlSalud" "S2_Cual" "S2_ECronica"
[64] "S3_Anticonceptivo" "S3_Cual" "S3_Edad"
[67] "S3_EdadPareja" "S3_Relaciones" "S4_CoitoI"
[70] "S4_Cual" "S4_DiaDespues" "S4_DIU"
[73] "S4_Inyecciones" "S4_Ninguno" "S4_Otro"
[76] "S4_Pastillas" "S4_Perodo" "S4_Preservativos"
[79] "S5_Embarazo" "S6_Hijos" "SYSTEMDATE"
[82] "T1_Artemarcial" "T1_Bailar" "T1_Basket"
[85] "T1_Correr" "T1_Deporte" "T1_Futbol"
[88] "T1_Gimnasio" "T1_Hockey" "T1_Natacion"
[91] "T1_Rugby" "T1_Skate" "T1_Surf"
[94] "T1_Tenis" "T1_Veces" "T1_Voley"
[97] "T2_Amigos" "T2_Calle" "T2_Casas"
[100] "T2_Centro" "T2_Club" "T2_Otros"
[103] "T2_Plaza" "T3_Bailar" "T3_Matinee"
[106] "T3_Noche" "T4_Compu" "T4_Leer"
[109] "T4_Libros" "T4_Revistas" "T5_Conectas"
[112] "T5_Redes" "T6_Consiste" "T6_Empleo"
[115] "T6_Horas" "T7_Cual" "T7_Iglesia"
[118] "T7_Religion" "Turno" "V1_Alegre"
[121] "V1_Enojado" "V1_Nervioso" "V1_Preocupado"
[124] "V1_Solo" "V1_Tranquilo" "V1_Triste"
[127] "V2_SentisEscuela" "V3_Casa" "V3_Escuela"
[130] "V3_Pareja" "V3_Violencia" "V4_Futuro"
[133] "V5_Cuales" "V5_Derechos" "V5_Drogas"
[136] "V5_Habitos" "V5_Otros" "V5_Ssexual"
[139] "V5_Violencia" "UniqueKey"
La función rename() posibilita renombrar a las variables de una tabla de datos.
La estructura básica es:
La variación rename_with() permite renombrar variables de una tabla a través de aplicar determinadas funciones.
La estructura básica de esta función es:
[1] "EDAD"
[1] "f5_amigo" "f5_familiar" "f5_nadie" "f5_novio"
[5] "f5_otro" "f5_profesional"
La función filter() del inglés filtrar, sirve para filtrar un subconjunto de observaciones (filas) de una tabla de datos a partir de una condición.
Para construir la condición se utilizan una serie de operadores de comparación y operadores lógicos similares a la de otros lenguajes de programación.
La estructura de la función puede ser cualquiera de las siguientes:
# filtramos observaciones que cumplan con la siguiente condición
datos |>
filter(F3_Sexo == 1,
between(F2_Edad, 17, 20),
H1_Cerveza == TRUE | H1_Vino == TRUE) |>
select(F3_Sexo, F2_Edad, H1_Cerveza, H1_Vino)# A tibble: 23 × 4
F3_Sexo F2_Edad H1_Cerveza H1_Vino
<dbl> <dbl> <lgl> <lgl>
1 1 18 TRUE FALSE
2 1 17 TRUE TRUE
3 1 18 TRUE FALSE
4 1 17 TRUE TRUE
5 1 17 FALSE TRUE
6 1 19 TRUE TRUE
7 1 18 TRUE TRUE
8 1 17 TRUE TRUE
9 1 18 TRUE TRUE
10 1 18 TRUE TRUE
# ℹ 13 more rows
La función arrange() del inglés ordenar, sirve para ordenar observaciones de una tabla de datos a partir de una o más variables (columnas).
El ordenamiento predeterminado es ascendente.
Si la variable contiene números, las filas se van a ordenar ubicando esos números de menor a mayor (1,2,3…). Si es texto, las filas se van a ordenar ubicando las palabras alfabéticamente en forma ascendente (a,b,c…).
Si deseamos invertir el orden debemos incorporar la función desc() dentro de arrange().
La función mutate() del inglés mutar o transformar, sirve para crear nuevas variables, a partir de los valores de otras variables, dentro de la tabla de datos.
La o las nuevas variables creadas se incorporan al final de las columnas del conjunto de datos.
Dentro de los argumentos de mutate() se aplican funciones vectorizadas, lo que significa que la función toma un vector de valores como entrada y devuelve el mismo número de valores como salida.
Algunas de las operaciones y funciones vectorizadas provistas por el lenguaje R son:
Operadores aritméticos - +, -, *, /, ^
Aritmética modular - %/% - %%
Transformación - escala - log() - log2() - log10() - exp() - sqrt()
Comparaciones - >, >=, <, <=, ==, !=
Atrasos/adelantos - lag() - lead()
Ordenamiento - min_rank() - percent_rank(), etc…
Acumulativos - cumsum() - cummean() - etc…
Condicional - if_else() - case_when().
Coercionamos la variable aplicando dmy() y as_date()
La función summarise() del inglés resumir, se utiliza justamente para resumir las observaciones de una tabla de datos mediante alguna medida resumen.
Otra forma de escribir la función es summarize(). Ambas realizan la misma operación.
Algunas de las funciones resumen provistas por el lenguaje R son:
tendencia central - mean() - median()
posición - min() - max() - quantile()
dispersión - var() - sd() - IQR()
conteo - n() - n_distinct()
orden - first() - last()
La mayoría de estas funciones aplican en tipos de datos int (enteros), dbl (reales), date (fecha) y ddtm (fecha - hora).
# Resumimos la variable F2_Edad calculando media,
# desvío estandar, mínimo y máximo
datos |>
summarise(Media = mean(F2_Edad, na.rm = T),
Desvio = sd(F2_Edad, na.rm = T),
Min = min(F2_Edad, na.rm = T),
Max = max(F2_Edad, na.rm = T)) # A tibble: 1 × 4
Media Desvio Min Max
<dbl> <dbl> <dbl> <dbl>
1 14.5 1.46 10 19
La función group_by() del inglés agrupar por, sirve para agrupar a partir de valores o categorías distintas.
Aplicado sólo no produce ningún resultado interesante, por eso está pensando para usarlo principalmente asociado a summarise().
Junto a esta función aparece ungroup() que deshace el agrupamiento.
# Resumimos la variable F2_Edad según Anio
# calculando media, desvío estandar, mínimo y máximo
datos |>
group_by(Anio) |>
summarise(Media = mean(F2_Edad, na.rm = T),
Desvio = sd(F2_Edad, na.rm = T),
Min = min(F2_Edad, na.rm = T),
Max = max(F2_Edad, na.rm = T)) # A tibble: 2 × 5
Anio Media Desvio Min Max
<chr> <dbl> <dbl> <dbl> <dbl>
1 2do. 13.7 1.03 10 18
2 4to. 15.8 1.06 13 19
El agrupamiento o estratificación producido por group_by() es permanente mientras no desagrupemos y esto a veces ocasiona problemas.
En la última versión de dplyr se agregó un argumento en summarise() para lograr agrupamientos temporales, donde no hace falta desagrupar posteriomente al resultado.
# Resumimos la variable F2_Edad según Anio con .by
# calculando media, desvío estandar, mínimo y máximo
datos |>
summarise(Media = mean(F2_Edad, na.rm = T),
Desvio = sd(F2_Edad, na.rm = T),
Min = min(F2_Edad, na.rm = T),
Max = max(F2_Edad, na.rm = T),
.by = Anio) # A tibble: 2 × 5
Anio Media Desvio Min Max
<chr> <dbl> <dbl> <dbl> <dbl>
1 4to. 15.8 1.06 13 19
2 2do. 13.7 1.03 10 18
La función count() del inglés contar, sirve para contabilizar categorías o valores diferentes de variables resumiendo los datos en una tabla de frecuencia.
Reconoce y también contabiliza los valores NA de las variables.
Tiene algunos argumentos opcionales como:
También se pueden agregar más variables separadas por una coma.
La función if_else() devuelve valores dependiendo del resultado de una condición lógica (TRUE/FALSE).
Los valores devueltos para cada observación se almacenan dentro de una variable definida en mutate().
# A tibble: 1 × 1
Mediana_edad
<dbl>
1 14
La función case_when() ejecuta una vectorización múltiple de funciones if_else().
Los valores devueltos para cada observación se almacenan dentro de una variable definida en mutate().
# etiquetamos la variable V1_Alegre
datos |>
mutate(V1_Alegre = case_when(
V1_Alegre == 0 ~ "Nada",
V1_Alegre == 1 ~ "Poco",
V1_Alegre == 2 ~ "Neutral",
V1_Alegre == 3 ~ "Muy",
V1_Alegre == 4 ~ "Totalmente",
.default = "Ns/Nc"
)) |>
count(V1_Alegre, sort = T)# A tibble: 6 × 2
V1_Alegre n
<chr> <int>
1 Totalmente 452
2 Muy 256
3 Neutral 249
4 Ns/Nc 171
5 Poco 80
6 Nada 44
La función between() es una función atajo para operaciones de condición >= x <= , implementado para vectores numéricos o de fecha/hora.
Se utiliza dentro de estructuras donde se escriben condiciones (filter(), mutate(), etc).
Los dos extremos (izquierda y derecha) se incluyen en el intervalo
Existen situaciones donde debemos analizar datos que se encuentran en diferentes tablas.
Con el fin de responder a nuestras preguntas de interés en ocasiones deberemos unirlas previamente.
De manera general, se le llama datos relacionales a esas múltiples tablas de datos que provienen muchas veces de sistemas de bases de datos construidas bajo el modelo relacional o bien cuando las tablas de datos tienen fuentes distintas pero comparten alguna variable común que permita “conectarlas”.
Para trabajar con datos relacionales necesitamos de funciones-verbos que vinculen pares de tablas.
Las tres familias de funciones del paquete dplyr diseñadas para trabajar con datos relacionales son:
Uniones de transformación (del inglés mutating joins), agregan nuevas variables a una tabla a partir de observaciones coincidentes de otra tabla.
Uniones de filtro (del inglés filtering joins), filtran observaciones de una tabla en función de la coincidencia o no coincidencia de otra tabla.
Operaciones en filas y columnas, sirven para unir tablas por columnas o por filas.
Las variables usadas para conectar cada par de variables se llaman claves (del inglés key)
Una clave es una variable (o un conjunto de variables) que identifican de manera única una observación.
Existen dos tipos de claves:
Una clave primaria identifica únicamente una observación en su propia tabla.
Una clave foránea únicamente identifica una observación en otra tabla.
Unión interior
La forma más simple de unión es la unión interior (del inglés inner join). Una unión interior une pares de observaciones siempre que sus claves sean iguales
Una unión interior mantiene las observaciones que aparecen en ambas tablas.
Función inner_join()
Uniones exteriores
Una unión exterior mantiene las observaciones que aparecen en al menos una de las tablas.
Función full_join()
Función left_join()
Función right_join()
Otra forma de ilustrar diferentes tipos de uniones es mediante un diagrama de Venn.
Sin embargo, tiene una limitante importante: un diagrama de Venn no puede mostrar qué ocurre con las claves que no identifican de manera única una observación
Hasta ahora todas las situaciones han asumido que las claves son únicas. Pero esto no siempre es así.
Existen dos posibilidades habituales:
Una tabla tiene claves duplicadas producto de una relación uno a varios.
Ambas tablas tienen claves duplicadas
Siempre que unimos claves duplicadas, obtenemos todas las posibles combinaciones, es decir, el producto cartesiano
Ejemplo con left_join()
semi_join()
Mantiene todas las observaciones de la tabla x donde la clave coincide con la clave de la tabla y
anti_join()
Descarta todas las observaciones de la tabla x donde la clave coincide con la clave de la tabla y
Identificar bien la variables que forman las claves de cada tabla.
Verificar la completitud de las claves. Si existe algún valor faltante no se podrá identificar la observación.
Verificar que las claves foráneas coinciden con las claves primarias de la otra tabla. Esto incluye comprobar coincidencia en el tipo de dato (numérico, caracter, etc)
Verificar claves duplicadas (se puede hacer aplicando count())
En algunas ocasiones necesitamos unir tablas que tienen formatos particulares por medio de filas o por medio de columnas.
Las funciones de dplyr para esta tarea son:
bind_rows() Une una tabla debajo de otra. Aplica cuando tenemos la misma estructura en tabla de datos divida en varios archivos (por ejemplo, producto de carga simultánea de datos en diferentes computadoras con diferentes data entry)
bind_cols() Une una tabla al lado de la otra. Es peligroso su uso si la confundimos con las uniones de transformación porque perdemos integridad de datos en las observaciones. Sirve sólo si el “orden” de las observaciones pueden garantizar la misma identidad de las partes a unir.
Llamamos tidy data o “datos ordenados” cuando:
Una variable se extiende por varias columnas.
Una observación está dispersa entre múltiples filas
Solución:
Usamos funciones pivot del paquete tidyr de tidyverse
Función pivot_longer() - Convierte nombres de variables en valores de una nueva variable.
Función pivot_wider() - Convierte valores de una variable en variables nuevas.
pivot_longer()Soluciona cuando una variable se extiende por varias columnas (las categorías estan en la cabecera).
Produce tablas “alargando” los datos, aumentando el número de filas y disminuyendo el número de columnas
pivot_wider()Soluciona cuando una observación está dispersa entre múltiples filas.
Produce tablas “estirando” los datos, aumentando el número de columnas y disminuyendo el número de filas.
Capítulo 3, 5 y 19 del libro “R for Data Science (2e)”
Instituto Nacional de Epidemiología